package com.zzyl.oss;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.IoUtil;
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.CredentialsProvider;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.*;
import java.net.URLDecoder;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

@SuppressWarnings("all")
@Slf4j
@Component
public class AliyunOSSOperator {
    @Autowired
    private AliyunOSSProperties ossProperties;


    //-----------------------------批量删除指定文件--------------------------------

    public void delBatch(List<String> fileNames) {
        OSS ossClient = null;
        try {
            String endpoint = ossProperties.getEndpoint();
            CredentialsProvider credentialsProvider = new DefaultCredentialProvider(
                    "LTAI5tFE3iuLSh8GpnnDEfXJ",
                    "uLZWTO6tzzOx4HaCrMrgo7H9tBqNLM");
            String bucketName = ossProperties.getBucketName();
            String region = "cn-hangzhou";
            ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
            clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
            ossClient = OSSClientBuilder.create()
                    .endpoint(endpoint)
                    .credentialsProvider(credentialsProvider)
                    .clientConfiguration(clientBuilderConfiguration)
                    .region(region)
                    .build();
            ///删除
            DeleteObjectsResult deleteObjectsResult = ossClient.deleteObjects(new DeleteObjectsRequest(bucketName)
                    .withKeys(fileNames)
                    .withEncodingType("url"));
            List<String> deletedObjects = deleteObjectsResult.getDeletedObjects();
            System.out.println(deletedObjects);
        } catch (Exception e) {
            log.error("批量删除oss文件失败，失败原因：{},删除失败的文件名称：{}", e.getMessage(),fileNames);
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
    //---------------------------------------------------------------------------------
    // 获取阿里云OSS 中所有的以 /年/月/日 所有文件列表 存储到 set 集合！

    public List<String> getFileNameFromOss(String filePrefix) {
        String endpoint = ossProperties.getEndpoint();
        CredentialsProvider credentialsProvider = new DefaultCredentialProvider(
                "LTAI5tFE3iuLSh8GpnnDEfXJ",
                "uLZWTO6tzzOx4HaCrMrgo7H9tBqNLM");
        String bucketName = ossProperties.getBucketName();
        String region = "cn-hangzhou";
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();

        List<String> fileNames = new ArrayList<String>();
        try {
            // 构造ListObjectsRequest请求。
            ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);
            // 设置prefix参数来获取fun目录下的所有文件。
            listObjectsRequest.setPrefix(filePrefix);
            // 递归列举fun目录下的所有文件。
            ObjectListing listing = ossClient.listObjects(listObjectsRequest);
            // 遍历所有文件。
            for (OSSObjectSummary objectSummary : listing.getObjectSummaries()) {
                fileNames.add(objectSummary.getKey());
            }
        } catch (Exception e) {
            log.error("查询指定前缀下文件失败，失败的原因是：{}", e.getMessage());
            return null;
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return fileNames;
    }
//----------------------------------------------------------------------------------

    /**
     * 文件下载
     *
     * @param fileName
     * @return
     */
    public InputStream downLoad(String fileName) {
        String endpoint = ossProperties.getEndpoint();
        String bucketName = ossProperties.getBucketName();
        CredentialsProvider credentialsProvider = new DefaultCredentialProvider("LTAI5tFE3iuLSh8GpnnDEfXJ", "uLZWTO6tzzOx4HaCrMrgo7H9tBqNLM");
        // 创建OSSClient实例。
        String region = "cn-hangzhou";
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();

        // 文件上传
        try {

            InputStream inputStream = ossClient.getObject(bucketName, fileName).getObjectContent();
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            // 读取文件内容到字节数组。
            byte[] readBuffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = inputStream.read(readBuffer)) != -1) {
                byteArrayOutputStream.write(readBuffer, 0, bytesRead);
            }
            // 获取最终的字节数组。
            byte[] fileBytes = byteArrayOutputStream.toByteArray();
            // 打印字节数组的长度。
            ByteArrayInputStream stream = IoUtil.toStream(fileBytes);
            // 数据读取完成后，获取的流必须关闭，否则会造成连接泄漏，导致请求无连接可用，程序无法正常工作。
            inputStream.close();
            byteArrayOutputStream.close();
            return stream;

        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }


    public String upload(byte[] content, String originalFilename) throws Exception {
        String endpoint = ossProperties.getEndpoint();
        String bucketName = ossProperties.getBucketName();
        // 从环境变量中获取访问凭证。运行本代码示例之前，请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        // EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();

        CredentialsProvider credentialsProvider = new DefaultCredentialProvider("LTAI5tFE3iuLSh8GpnnDEfXJ", "uLZWTO6tzzOx4HaCrMrgo7H9tBqNLM");

        // 填写Object完整路径，例如202406/1.png。Object完整路径中不能包含Bucket名称。
        // 获取当前系统日期的字符串,格式为 yyyy/MM
        String dir = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
        // 根据原始文件名originalFilename, 生成一个新的不重复的文件名
        String newFileName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."));
        String objectName = dir + "/" + newFileName;

        // 创建OSSClient实例。
        String region = "cn-hangzhou";
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();

        // 文件上传
        try {
            ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content));
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }

        return endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + objectName;
    }
}
